#include "EventLoopThread.h"
#include "EventLoop.h"

EventLoopThread::EventLoopThread(const ThreadInitCallback& cb, const std::string& name)
  : m_loop(nullptr)
  , m_exiting(false)
  , m_thread(std::bind(&EventLoopThread::threadFunc, this), name)
  , m_mutex()
  , m_cond()
  , m_initCallback(cb)
{
  
}
EventLoopThread::~EventLoopThread()
{
  m_exiting = true;
  stopLoop();
}
EventLoop* EventLoopThread::startLoop()
{
  m_thread.start(); // 启动底层的新线程
  EventLoop* loop = nullptr;
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    m_cond.wait(lock, [this] { return m_loop != nullptr; });
    loop = m_loop;
  }
  return loop;
}

void EventLoopThread::threadFunc()
{
  EventLoop loop; // 创建一个独立的 EventLoop，和上面的线程是一一对应的，one loop per thread
  if (m_initCallback) {
    m_initCallback(&loop);
  }
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    m_loop = &loop;
    m_cond.notify_one();
  }
  loop.loop(); // 开启底层的 poller 的 poll 开始监听
  std::unique_lock<std::mutex> lock(m_mutex);
  m_loop = nullptr; // 线程退出后置 nullptr
}

// 平滑退出
void EventLoopThread::stopLoop()
{
  if (m_loop == nullptr) {
    return;
  }
  // 等待当前任务完成再退出
  m_loop->queueInLoop([this] {m_loop->quit();});
  m_thread.join();
}